home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 1.iso / HENSA / MATHS / PLPLOT / PLPLOT.ZIP / src / plargs.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-30  |  41.3 KB  |  1,591 lines

  1. /* $Id: plargs.c,v 1.21 1994/06/30 18:21:58 mjl Exp $
  2.  * $Log: plargs.c,v $
  3.  * Revision 1.21  1994/06/30  18:21:58  mjl
  4.  * All core source files: made another pass to eliminate warnings when using
  5.  * gcc -Wall.  Lots of cleaning up: got rid of includes of math.h or string.h
  6.  * (now included by plplot.h), and other minor changes.  Now each file has
  7.  * global access to the plstream pointer via extern; many accessor functions
  8.  * eliminated as a result.
  9.  *
  10.  * Revision 1.20  1994/05/16  21:29:39  mjl
  11.  * Changes to plSetInternalOpt: the first argument is no longer required to
  12.  * have a leading dash.
  13.  *
  14.  * Revision 1.19  1994/03/23  07:50:37  mjl
  15.  * Added new plplot base options:
  16.  *
  17.  *  -hack        Set to enable some driver-specific hack
  18.  *  -fbeg number    First family member number on output
  19.  *  -finc number    Increment between family members
  20.  *  -fflen length    Family member number minimum field width
  21.  *
  22.  * Revision 1.18  1994/02/01  22:47:49  mjl
  23.  * Added -user <user> flag, for specifying user when invoking plserver
  24.  * remotely (via remsh).
  25.  *
  26.  * Revision 1.17  1994/01/25  06:38:26  mjl
  27.  * -db option (double buffering) added, for use with any of the X-based
  28.  * drivers.  This holds the window fixed while drawing only into the pixmap,
  29.  * until the end of page is seen.  Then the contents of the pixmap are
  30.  * blitted to the window.  This allows for an animation-type facility for
  31.  * properly constructed sequences (e.g. fixed axes) of plots.  Note, however,
  32.  * that this is no substitute for a /real/ animation capability since
  33.  * the speed of playback is determined by how much data has to be read
  34.  * and processed for each frame (thus can be somewhat variable).
  35.  *
  36.  * Revision 1.16  1994/01/15  17:28:22  mjl
  37.  * Added new args: -server_name, -server_host, -server_port.  -server_name is
  38.  * used with the TK driver to specify plserver's TK main window name, if
  39.  * already running.  -server_host and -server_port are used for the DP
  40.  * driver, for specifying the host to run it on, and the communications port
  41.  * (if already running).
  42. */
  43.  
  44. /*
  45.     plargs.c
  46.  
  47.     Copyright 1993
  48.     Maurice LeBrun
  49.  
  50.     This software may be freely copied, modified and redistributed without
  51.     fee provided that this copyright notice is preserved intact on all
  52.     copies and modified copies.
  53.  
  54.     There is no warranty or other guarantee of fitness of this software.
  55.     It is provided solely "as is". The author(s) disclaim(s) all
  56.     responsibility and liability with respect to this software's usage or
  57.     its effect upon hardware or computer systems.
  58.  
  59. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  60.  
  61.     This file contains routines to extract & process command flags.  The
  62.     command flags recognized by PLPLOT are stored in the "ploption_table"
  63.     structure, along with strings giving the syntax, long help message,
  64.     and option handler.  The command line parser removes all recognized
  65.     flags (decreasing argc accordingly), so that invalid input may be
  66.     readily detected.  These routines can also be used to process user
  67.     command line flags.
  68.  
  69.     The command line parsers (one for internal plplot flags, one for
  70.     user-specified flags) accept a variable "mode" which can have
  71.     the following bits set:
  72.  
  73.     PL_PARSE_FULL -- Full parsing of command line and all error messages
  74.     enabled, including program exit when an error occurs.  This is
  75.     automatically set when calling plParseInternalOpts().  User programs
  76.     that have other command flags should not use this, in which case the
  77.     caller must issue help and syntax messages.  In both cases syntax
  78.     and help messages may still be printed when appropriate.  
  79.  
  80.     PL_PARSE_QUIET -- Turns off all output except in the case of
  81.     errors.
  82.  
  83.     PL_PARSE_NODELETE -- Turns off deletion of processed arguments.
  84.  
  85.     PL_PARSE_SHOWALL -- Show invisible options 
  86.  
  87.     PL_PARSE_OVERRIDE -- Compares user option table to internal one, and
  88.     disables all internal options that match user options.  Has no effect
  89.     in plParseInternalOpts() or plSetInternalOpt() calls.
  90.  
  91.     PL_PARSE_NOPROGRAM -- Specified if argv[0] is NOT a pointer to the
  92.     program name.
  93.  
  94.     PL_PARSE_NODASH -- Set if leading dash is NOT required.
  95.  
  96.     Note that the parser for user-defined flags accepts a pointer to a
  97.     function to be called when an error is detected, to allow an
  98.     appropriate usage message to be issued.
  99.  
  100.     See plrender.c for examples of actual usage.
  101.  
  102.     A nice enhancement would be support for adding more option tables to
  103.     be checked, where each would presumably originate from additional
  104.     libraries supporting command line options.  When added a flag would
  105.     specify how name clashes are to be handled (possibly supporting all
  106.     three cases: one table dominates, or handle them on an even footing
  107.     if the options are compatible).  Also a scheme would have to be
  108.     worked out to intelligently handle the combined syntax and help
  109.     entries.  Note this may NOT always help in combining options since
  110.     sometimes a certain order must be retained (e.g. plrender follows
  111.     the order: process plrender options, read metafile header, process
  112.     plplot options).
  113. */
  114.  
  115. #include "plplotP.h"
  116. #include <ctype.h>
  117.  
  118. /* Support functions */
  119. /* INDENT OFF */
  120.  
  121. static int  ParseOpt    (int *, char ***, int *, char ***, PLOptionTable *);
  122. static int  ProcessOpt    (char *, PLOptionTable *, int *, char ***, int *);
  123. static int  GetOptarg    (char **, int *, char ***, int *);
  124. static void Usage    (char *);
  125. static void Help    (void);
  126. static void Syntax    (void);
  127.  
  128. static void (*UsageH) (char *) = Usage;
  129.  
  130. /* Option handlers */
  131.  
  132. static int opt_h        (char *, char *, void *);
  133. static int opt_v        (char *, char *, void *);
  134. static int opt_hack        (char *, char *, void *);
  135. static int opt_dev        (char *, char *, void *);
  136. static int opt_o        (char *, char *, void *);
  137. static int opt_geo        (char *, char *, void *);
  138. static int opt_a        (char *, char *, void *);
  139. static int opt_jx        (char *, char *, void *);
  140. static int opt_jy        (char *, char *, void *);
  141. static int opt_mar        (char *, char *, void *);
  142. static int opt_ori        (char *, char *, void *);
  143. static int opt_width        (char *, char *, void *);
  144. static int opt_bg        (char *, char *, void *);
  145. static int opt_fam        (char *, char *, void *);
  146. static int opt_fsiz        (char *, char *, void *);
  147. static int opt_fbeg        (char *, char *, void *);
  148. static int opt_finc        (char *, char *, void *);
  149. static int opt_fflen        (char *, char *, void *);
  150. static int opt_bufmax        (char *, char *, void *);
  151. static int opt_nopixmap        (char *, char *, void *);
  152. static int opt_db        (char *, char *, void *);
  153. static int opt_np        (char *, char *, void *);
  154. static int opt_px        (char *, char *, void *);
  155. static int opt_py        (char *, char *, void *);
  156. static int opt_wplt        (char *, char *, void *);
  157.  
  158. static int opt_plserver        (char *, char *, void *);
  159. static int opt_plwindow        (char *, char *, void *);
  160. static int opt_tcl_cmd        (char *, char *, void *);
  161. static int opt_auto_path    (char *, char *, void *);
  162. static int opt_bufmax        (char *, char *, void *);
  163. static int opt_server_name    (char *, char *, void *);
  164. static int opt_server_host    (char *, char *, void *);
  165. static int opt_server_port    (char *, char *, void *);
  166. static int opt_user        (char *, char *, void *);
  167.  
  168. /* Global variables */
  169.  
  170. static char    *program_name = "<user program>";
  171.  
  172. static int    mode_full;
  173. static int    mode_quiet;
  174. static int    mode_nodelete;
  175. static int    mode_showall;
  176. static int    mode_noprogram;
  177. static int    mode_override;
  178. static int    mode_nodash;
  179.  
  180. /*----------------------------------------------------------------------*\
  181.  * PLPLOT options data structure definition.
  182.  *
  183.  * The table is defined as follows
  184.  *
  185.  * typedef struct {
  186.  *     char *opt;
  187.  *     int  (*handler)    (char *, char *, void *);
  188.  *     void *client_data;
  189.  *     void *var;
  190.  *     long mode;
  191.  *     char *syntax;
  192.  *     char *desc;
  193.  * } PLOptionTable;
  194.  *
  195.  * where each entry has the following meaning:
  196.  *
  197.  * opt        option string
  198.  * handler    pointer to function for processing the option and
  199.  *         (optionally) its argument
  200.  * client_data    pointer to data that gets passed to (*handler)
  201.  * var        address of variable to set based on "mode"
  202.  * mode        governs handling of option (see below)
  203.  * syntax    short syntax description
  204.  * desc        long syntax description
  205.  *
  206.  * The syntax and or desc strings can be NULL if the option is never to be
  207.  * described.  Usually this is only used for obsolete arguments; those we
  208.  * just wish to hide from normal use are better made invisible (which are
  209.  * made visible by either specifying -showall first or PL_PARSE_SHOWALL).
  210.  *
  211.  * The mode bits are:
  212.  *
  213.  * PL_OPT_ENABLED    Processing for option is enabled
  214.  * PL_OPT_ARG        Option has an argment 
  215.  * PL_OPT_NODELETE    Don't delete after processing 
  216.  * PL_OPT_INVISIBLE    Make invisible (usually for debugging)
  217.  *
  218.  * The following mode bits cause the option to be processed as specified:
  219.  *
  220.  * PL_OPT_FUNC        Call function handler (opt, optarg)
  221.  * PL_OPT_BOOL        Set *var=1
  222.  * PL_OPT_INT        Set *var=atoi(optarg)
  223.  * PL_OPT_FLOAT        Set *var=atof(optarg)
  224.  * PL_OPT_STRING        Set var=optarg
  225.  *
  226.  * where opt points to the option string and optarg points to the
  227.  * argument string.
  228.  *
  229. \*----------------------------------------------------------------------*/
  230.  
  231. static PLOptionTable ploption_table[] = {
  232. {
  233.     "showall",            /* Turns on invisible options */
  234.     NULL,
  235.     NULL,
  236.     &mode_showall,
  237.     PL_OPT_BOOL | PL_OPT_ENABLED | PL_OPT_INVISIBLE,
  238.     "-showall",
  239.     "Turns on invisible options" },
  240. {
  241.     "h",            /* Help */
  242.     opt_h,
  243.     NULL,
  244.     NULL,
  245.     PL_OPT_FUNC | PL_OPT_ENABLED,
  246.     "-h",
  247.     "Print out this message" },
  248. {
  249.     "v",            /* Version */
  250.     opt_v,
  251.     NULL,
  252.     NULL,
  253.     PL_OPT_FUNC | PL_OPT_ENABLED,
  254.     "-v",
  255.     "Print out the plplot library version number" },
  256. {
  257.     "hack",            /* Enable driver-specific hack(s) */
  258.     opt_hack,
  259.     NULL,
  260.     NULL,
  261.     PL_OPT_FUNC | PL_OPT_ENABLED | PL_OPT_INVISIBLE,
  262.     "-hack",
  263.     "Enable driver-specific hack(s)" },
  264. {
  265.     "dev",            /* Output device */
  266.     opt_dev,
  267.     NULL,
  268.     NULL,
  269.     PL_OPT_FUNC | PL_OPT_ENABLED | PL_OPT_ARG,
  270.     "-dev name",
  271.     "Output device name" },
  272. {
  273.     "o",            /* Output filename */
  274.     opt_o,
  275.     NULL,
  276.     NULL,
  277.     PL_OPT_FUNC | PL_OPT_ENABLED | PL_OPT_ARG,
  278.     "-o name",
  279.     "Output filename" },
  280. {
  281.     "display",            /* X server */
  282.     opt_o,
  283.     NULL,
  284.     NULL,
  285.     PL_OPT_FUNC | PL_OPT_ENABLED | PL_OPT_ARG,
  286.     "-display name",
  287.     "X server to contact" },
  288. {
  289.     "px",            /* Plots per page in x */
  290.     opt_px,
  291.     NULL,
  292.     NULL,
  293.     PL_OPT_FUNC | PL_OPT_ENABLED | PL_OPT_ARG,
  294.     "-px number",
  295.     "Plots per page in x" },
  296. {
  297.     "py",            /* Plots per page in y */
  298.     opt_py,
  299.     NULL,
  300.     NULL,
  301.     PL_OPT_FUNC | PL_OPT_ENABLED | PL_OPT_ARG,
  302.     "-py number",
  303.     "Plots per page in y" },
  304. {
  305.     "geometry",            /* Geometry */
  306.     opt_geo,
  307.     NULL,
  308.     NULL,
  309.     PL_OPT_FUNC | PL_OPT_ENABLED | PL_OPT_ARG,
  310.     "-geometry geom",
  311.     "Window size, in pixels (e.g. -geometry 400x300)" },
  312. {
  313.     "geo",            /* Geometry (alias) */
  314.     opt_geo,
  315.     NULL,
  316.     NULL,
  317.     PL_OPT_FUNC | PL_OPT_ENABLED | PL_OPT_ARG | PL_OPT_INVISIBLE,
  318.     "-geo geom",
  319.     "Window size, in pixels (e.g. -geo 400x300)" },
  320. {
  321.     "wplt",            /* Plot window */
  322.     opt_wplt,
  323.     NULL,
  324.     NULL,
  325.     PL_OPT_FUNC | PL_OPT_ENABLED | PL_OPT_ARG,
  326.     "-wplt xl,yl,xr,yr",
  327.     "Relative coordinates [0-1] of window into plot" },
  328. {
  329.     "mar",            /* Margin */
  330.     opt_mar,
  331.     NULL,
  332.     NULL,
  333.     PL_OPT_FUNC | PL_OPT_ENABLED | PL_OPT_ARG,
  334.     "-mar margin",
  335.     "Margin space in relative coordinates (0 to 0.5, def 0)" },
  336. {
  337.     "a",            /* Aspect ratio */
  338.     opt_a,
  339.     NULL,
  340.     NULL,
  341.     PL_OPT_FUNC | PL_OPT_ENABLED | PL_OPT_ARG,
  342.     "-a aspect",
  343.     "Page aspect ratio (def: same as output device)"},
  344. {
  345.     "jx",            /* Justification in x */
  346.     opt_jx,
  347.     NULL,
  348.     NULL,
  349.     PL_OPT_FUNC | PL_OPT_ENABLED | PL_OPT_ARG,
  350.     "-jx justx",
  351.     "Page justification in x (-0.5 to 0.5, def 0)"},
  352. {
  353.     "jy",            /* Justification in y */
  354.     opt_jy,
  355.     NULL,
  356.     NULL,
  357.     PL_OPT_FUNC | PL_OPT_ENABLED | PL_OPT_ARG,
  358.     "-jy justy",
  359.     "Page justification in y (-0.5 to 0.5, def 0)"},
  360. {
  361.     "ori",            /* Orientation */
  362.     opt_ori,
  363.     NULL,
  364.     NULL,
  365.     PL_OPT_FUNC | PL_OPT_ENABLED | PL_OPT_ARG,
  366.     "-ori orient",
  367.     "Plot orientation (0,2=landscape, 1,3=portrait)" },
  368. {
  369.     "width",            /* Pen width */
  370.     opt_width,
  371.     NULL,
  372.     NULL,
  373.     PL_OPT_FUNC | PL_OPT_ENABLED | PL_OPT_ARG,
  374.     "-width width",
  375.     "Sets pen width (1 <= width <= 10)" },
  376. {
  377.     "bg",            /* Background color */
  378.     opt_bg,
  379.     NULL,
  380.     NULL,
  381.     PL_OPT_FUNC | PL_OPT_ENABLED | PL_OPT_ARG,
  382.     "-bg color",
  383.     "Background color (0=black, FFFFFF=white)" },
  384. {
  385.     "fam",            /* Familying on switch */
  386.     opt_fam,
  387.     NULL,
  388.     NULL,
  389.     PL_OPT_FUNC | PL_OPT_ENABLED,
  390.     "-fam",
  391.     "Create a family of output files" },
  392. {
  393.     "fsiz",            /* Family file size */
  394.     opt_fsiz,
  395.     NULL,
  396.     NULL,
  397.     PL_OPT_FUNC | PL_OPT_ENABLED | PL_OPT_ARG,
  398.     "-fsiz size",
  399.     "Output family file size in MB (e.g. -fsiz 1.0)" },
  400. {
  401.     "fbeg",            /* Family starting member */
  402.     opt_fbeg,
  403.     NULL,
  404.     NULL,
  405.     PL_OPT_FUNC | PL_OPT_ENABLED | PL_OPT_ARG,
  406.     "-fbeg number",
  407.     "First family member number on output" },
  408. {
  409.     "finc",            /* Family member increment */
  410.     opt_finc,
  411.     NULL,
  412.     NULL,
  413.     PL_OPT_FUNC | PL_OPT_ENABLED | PL_OPT_ARG,
  414.     "-finc number",
  415.     "Increment between family members" },
  416. {
  417.     "fflen",            /* Family member min field width */
  418.     opt_fflen,
  419.     NULL,
  420.     NULL,
  421.     PL_OPT_FUNC | PL_OPT_ENABLED | PL_OPT_ARG,
  422.     "-fflen length",
  423.     "Family member number minimum field width" },
  424. {
  425.     "nopixmap",            /* Do not use pixmaps */
  426.     opt_nopixmap,
  427.     NULL,
  428.     NULL,
  429.     PL_OPT_FUNC | PL_OPT_ENABLED,
  430.     "-nopixmap",
  431.     "Don't use pixmaps in X-based drivers" },
  432. {
  433.     "db",            /* Double buffering on switch */
  434.     opt_db,
  435.     NULL,
  436.     NULL,
  437.     PL_OPT_FUNC | PL_OPT_ENABLED,
  438.     "-db",
  439.     "Double buffer X window output" },
  440. {
  441.     "np",            /* Page pause off switch */
  442.     opt_np,
  443.     NULL,
  444.     NULL,
  445.     PL_OPT_FUNC | PL_OPT_ENABLED,
  446.     "-np",
  447.     "No pause between pages" },
  448. {
  449.     "bufmax",            /* # bytes sent before flushing output */
  450.     opt_bufmax,
  451.     NULL,
  452.     NULL,
  453.     PL_OPT_FUNC | PL_OPT_ENABLED | PL_OPT_ARG | PL_OPT_INVISIBLE,
  454.     "-bufmax",
  455.     "bytes sent before flushing output" },
  456. {
  457.     "server_name",            /* Main window name of server */
  458.     opt_server_name,
  459.     NULL,
  460.     NULL,
  461.     PL_OPT_FUNC | PL_OPT_ENABLED | PL_OPT_ARG,
  462.     "-server_name name",
  463.     "Main window name of plplot server (tk driver)" },
  464. {
  465.     "server_host",            /* Host to run server on */
  466.     opt_server_host,
  467.     NULL,
  468.     NULL,
  469.     PL_OPT_FUNC | PL_OPT_ENABLED | PL_OPT_ARG,
  470.     "-server_host name",
  471.     "Host to run plplot server on (dp driver)" },
  472. {
  473.     "server_port",            /* Port to talk to server on */
  474.     opt_server_port,
  475.     NULL,
  476.     NULL,
  477.     PL_OPT_FUNC | PL_OPT_ENABLED | PL_OPT_ARG,
  478.     "-server_port name",
  479.     "Port to talk to plplot server on (dp driver)" },
  480. {
  481.     "user",                /* user name on remote node */
  482.     opt_user,
  483.     NULL,
  484.     NULL,
  485.     PL_OPT_FUNC | PL_OPT_ENABLED | PL_OPT_ARG,
  486.     "-user name",
  487.     "User name on remote node (dp driver)" },
  488. {
  489.     "plserver",            /* plplot server name */
  490.     opt_plserver,
  491.     NULL,
  492.     NULL,
  493.     PL_OPT_FUNC | PL_OPT_ENABLED | PL_OPT_ARG | PL_OPT_INVISIBLE,
  494.     "-plserver name",
  495.     "Invoked name of plplot server (tk or dp driver)" },
  496. {
  497.     "plwindow",            /* plplot container window name */
  498.     opt_plwindow,
  499.     NULL,
  500.     NULL,
  501.     PL_OPT_FUNC | PL_OPT_ENABLED | PL_OPT_ARG | PL_OPT_INVISIBLE,
  502.     "-plwindow name",
  503.     "Name of plplot container window (tk or dp driver)" },
  504. {
  505.     "tcl_cmd",            /* TCL initialization command */
  506.     opt_tcl_cmd,
  507.     NULL,
  508.     NULL,
  509.     PL_OPT_FUNC | PL_OPT_ENABLED | PL_OPT_ARG | PL_OPT_INVISIBLE,
  510.     "-tcl_cmd command",
  511.     "TCL command string run at startup (note: disabled)" },
  512. {
  513.     "auto_path",        /* Additional directory(s) to autoload */
  514.     opt_auto_path,
  515.     NULL,
  516.     NULL,
  517.     PL_OPT_FUNC | PL_OPT_ENABLED | PL_OPT_ARG | PL_OPT_INVISIBLE,
  518.     "-auto_path dir",
  519.     "Additional directory(s) to autoload (tk or dp driver)" },
  520. {
  521.     NULL,            /* option */
  522.     NULL,            /* handler */
  523.     NULL,            /* client data */
  524.     NULL,            /* address of variable to set */
  525.     0,                /* mode flag */
  526.     NULL,            /* short syntax */
  527.     NULL }            /* long syntax */
  528. };
  529.  
  530. static char *notes[] = {
  531. "All parameters must be white-space delimited.  Some options are driver",
  532. "dependent.  Please see the plplot reference document for more detail.",
  533. NULL};
  534.  
  535. /* INDENT ON */
  536. /*----------------------------------------------------------------------*\
  537.  * The following routines contain some code derived from "xterm.c" and
  538.  * "ParseCmd.c" of the X-windows Version 11 distribution.  The copyright
  539.  * notice is reproduced here:
  540.  
  541. Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
  542. and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
  543.  
  544.                         All Rights Reserved
  545.  
  546.  * The full permission notice is given in the plplot documentation.
  547. \*----------------------------------------------------------------------*/
  548.  
  549. /*----------------------------------------------------------------------*\
  550.  * plSyntax()
  551.  *
  552.  * Front-end to Syntax() for external use.
  553.  * Accepts mode flag (right now only PL_PARSE_SHOWALL bit is used).
  554. \*----------------------------------------------------------------------*/
  555.  
  556. void
  557. plSyntax(PLINT mode)
  558. {
  559.     mode_showall   = mode & PL_PARSE_SHOWALL;
  560.     Syntax();
  561. }
  562.  
  563. /*----------------------------------------------------------------------*\
  564.  * plHelp()
  565.  *
  566.  * Front-end to Help() for external use.
  567.  * Accepts mode flag (right now only PL_PARSE_SHOWALL bit is used).
  568. \*----------------------------------------------------------------------*/
  569.  
  570. void
  571. plHelp(PLINT mode)
  572. {
  573.     mode_showall   = mode & PL_PARSE_SHOWALL;
  574.     Help();
  575. }
  576.  
  577. /*----------------------------------------------------------------------*\
  578.  * plNotes()
  579.  *
  580.  * Print usage notes.
  581. \*----------------------------------------------------------------------*/
  582.  
  583. void
  584. plNotes(void)
  585. {
  586.     char **cpp;
  587.  
  588.     putc('\n', stderr);
  589.     for (cpp = notes; *cpp; cpp++) {
  590.     fputs(*cpp, stderr);
  591.     putc('\n', stderr);
  592.     }
  593.     putc('\n', stderr);
  594. }
  595.  
  596. /*----------------------------------------------------------------------*\
  597.  * plParseInternalOpts()
  598.  *
  599.  * Process plplot internal options list
  600.  * If mode is PL_PARSE_FULL, exit on an error.
  601. \*----------------------------------------------------------------------*/
  602.  
  603. int
  604. plParseInternalOpts(int *p_argc, char **argv, PLINT mode)
  605. {
  606.     int status;
  607.  
  608.     mode &= ~PL_PARSE_OVERRIDE;
  609.     status = plParseOpts(p_argc, argv, mode, ploption_table, NULL);
  610.  
  611.     return(status);
  612. }
  613.  
  614. /*----------------------------------------------------------------------*\
  615.  * plSetInternalOpt()
  616.  *
  617.  * Process input strings, treating them as an option and argument pair.
  618.  * Returns 1 on an error.
  619. \*----------------------------------------------------------------------*/
  620.  
  621. int
  622. plSetInternalOpt(char *opt, char *optarg)
  623. {
  624.     int mode = 0, argc = 2, status;
  625.     char *argv[3];
  626.  
  627.     argv[0] = opt;
  628.     argv[1] = optarg;
  629.     argv[2] = NULL;
  630.     mode =
  631.     PL_PARSE_QUIET |
  632.     PL_PARSE_NODELETE |
  633.     PL_PARSE_NOPROGRAM |
  634.     PL_PARSE_NODASH;
  635.  
  636.     status = plParseOpts(&argc, argv, mode, ploption_table, NULL);
  637.     if (status) {
  638.     fprintf( stderr, "plSetInternalOpt: Unrecognized option %s\n", opt);
  639.     }
  640.     return(status);
  641. }
  642.  
  643. /*----------------------------------------------------------------------*\
  644.  * plParseOpts()
  645.  *
  646.  * Process options list
  647.  * An error in parsing the argument list causes a program exit if
  648.  * mode_full is set, otherwise the function returns with an error.
  649. \*----------------------------------------------------------------------*/
  650.  
  651. int
  652. plParseOpts(int *p_argc, char **argv, PLINT mode, PLOptionTable *option_table,
  653.         void (*usage_handler) (char *))
  654. {
  655.     char **argsave, **argend;
  656.     int    myargc, status = 0;
  657.     PLOptionTable *tab, *pltab;
  658.  
  659. /* Initialize */
  660.  
  661.     mode_full      = mode & PL_PARSE_FULL;
  662.     mode_quiet     = mode & PL_PARSE_QUIET;
  663.     mode_nodelete  = mode & PL_PARSE_NODELETE;
  664.     mode_showall   = mode & PL_PARSE_SHOWALL;
  665.     mode_noprogram = mode & PL_PARSE_NOPROGRAM;
  666.     mode_override  = mode & PL_PARSE_OVERRIDE;
  667.     mode_nodash    = mode & PL_PARSE_NODASH;
  668.  
  669.     myargc = (*p_argc); 
  670.     argend = argv + myargc;
  671.     if (usage_handler != NULL)
  672.     UsageH = usage_handler;
  673.  
  674. /* Disable internal options that match user options if mode_override is set */
  675.  
  676.     if (mode_override) {
  677.     for (tab = option_table; tab->opt; tab++) {
  678.         for (pltab = ploption_table; pltab->opt; pltab++) {
  679.         if ( ! (pltab->mode & PL_OPT_ENABLED)) 
  680.             continue;
  681.  
  682.         if (*tab->opt == *pltab->opt &&
  683.             ! strcmp(tab->opt, pltab->opt)) {
  684.             pltab->mode &= ! PL_OPT_ENABLED;
  685.         }
  686.         }
  687.     }
  688.     }
  689.  
  690. /* If program name is first argument, save and advance */
  691.  
  692.     if ( ! mode_noprogram) {
  693.     program_name = argv[0];
  694.     plsc->program = argv[0];
  695.  
  696.     --myargc; ++argv;
  697.     argsave = argv;
  698.     }
  699.  
  700.     if (myargc == 0)
  701.     return 0;
  702.  
  703. /* Process the command line */
  704.  
  705.     for (; myargc > 0; --myargc, ++argv) {
  706.     status = ParseOpt(&myargc, &argv, p_argc, &argsave, option_table);
  707.     if (status) {
  708.         if (mode_full)
  709.         exit(1);
  710.         else
  711.         break;
  712.     }
  713.     }
  714.  
  715. /* NULL-terminate compressed argv */
  716.  
  717.     if ( ! mode_nodelete && (argsave < argend))
  718.     (*argsave) = NULL;
  719.  
  720.     return(status);
  721. }
  722.  
  723. /*----------------------------------------------------------------------*\
  724.  * ParseOpt()
  725.  *
  726.  * Parses & determines appropriate action for input flag.
  727. \*----------------------------------------------------------------------*/
  728.  
  729. static int
  730. ParseOpt(int *p_myargc, char ***p_argv, int *p_argc, char ***p_argsave,
  731.      PLOptionTable *option_table)
  732. {
  733.     PLOptionTable *tab;
  734.     char *opt;
  735.  
  736. /* Only handle actual flags and their arguments */
  737.  
  738.     if ( mode_nodash || (*p_argv)[0][0] == '-') {
  739.  
  740.     opt = (*p_argv)[0];
  741.     if (*opt == '-') 
  742.         opt++;
  743.  
  744.     for (tab = option_table; tab->opt; tab++) {
  745.  
  746. /* Skip if option not enabled */
  747.  
  748.         if ( ! (tab->mode & PL_OPT_ENABLED)) 
  749.         continue;
  750.  
  751.         if (*opt == *tab->opt && ! strcmp(opt, tab->opt)) {
  752.  
  753. /* Option matched, so remove from argv list if applicable. */
  754.  
  755.         if ( ! mode_nodelete) {
  756.             if (tab->mode & PL_OPT_NODELETE)
  757.             (*(*p_argsave)++) = (**p_argv);
  758.             else
  759.             --(*p_argc);
  760.         }
  761.  
  762. /* Process option (and argument if applicable) */
  763.  
  764.         return(ProcessOpt(opt, tab, p_myargc, p_argv, p_argc));
  765.         }
  766.     }
  767.     }
  768.  
  769. /* If control reaches here the argument is unrecognized */
  770.  
  771.     if ( ! mode_nodelete)
  772.     (*(*p_argsave)++) = (**p_argv);  /* compress arglist */ 
  773.  
  774.     if (mode_full) {
  775.     if ( ! mode_quiet)
  776.         (*UsageH) (**p_argv);
  777.     return 1;
  778.     }
  779.     else
  780.     return 0;
  781. }
  782.  
  783. /*----------------------------------------------------------------------*\
  784.  * ProcessOpt()
  785.  *
  786.  * Process option (and argument if applicable).
  787. \*----------------------------------------------------------------------*/
  788.  
  789. static int
  790. ProcessOpt(char *opt, PLOptionTable *tab, int *p_myargc, char ***p_argv,
  791.        int *p_argc)
  792. {
  793.     int need_arg;
  794.     char *optarg = NULL;
  795.  
  796. /* Get option argument if necessary */
  797.  
  798.     need_arg = PL_OPT_ARG | PL_OPT_INT | PL_OPT_FLOAT | PL_OPT_STRING;
  799.  
  800.     if (tab->mode & need_arg) {
  801.     if (GetOptarg(&optarg, p_myargc, p_argv, p_argc))
  802.         return 1;
  803.     }
  804.  
  805. /* Process argument */
  806.  
  807.     switch (tab->mode & 0xFF00) {
  808.  
  809. /* Call function handler to do the job */
  810.  
  811.       case PL_OPT_FUNC:
  812.  
  813.     if (tab->handler == NULL) {
  814.         fprintf(stderr,
  815.             "ProcessOpt: no handler specified for option %s\n",
  816.             tab->opt);
  817.         return 1;
  818.     }
  819.     return( (*tab->handler) (opt, optarg, tab->client_data) );
  820.  
  821. /* Set *var as a boolean */
  822.  
  823.       case PL_OPT_BOOL:
  824.     if (tab->var == NULL) {
  825.         fprintf(stderr,
  826.             "ProcessOpt: no variable specified for option %s\n",
  827.             tab->opt);
  828.         return 1;
  829.     }
  830.     *(int *)tab->var = 1;
  831.     break;
  832.  
  833. /* Set *var as an int */
  834.  
  835.       case PL_OPT_INT:
  836.     if (tab->var == NULL) {
  837.         fprintf(stderr,
  838.             "ProcessOpt: no variable specified for option %s\n",
  839.             tab->opt);
  840.         return 1;
  841.     }
  842.     *(int *)tab->var = atoi(optarg);
  843.     break;
  844.  
  845. /* Set *var as a float */
  846.  
  847.       case PL_OPT_FLOAT:
  848.     if (tab->var == NULL) {
  849.         fprintf(stderr,
  850.             "ProcessOpt: no variable specified for option %s\n",
  851.             tab->opt);
  852.         return 1;
  853.     }
  854.     *(float *)tab->var = atof(optarg);
  855.     break;
  856.  
  857. /* Set var (can be NULL initially) to point to optarg string */
  858.  
  859.       case PL_OPT_STRING:
  860.     tab->var = optarg;
  861.     break;
  862.  
  863. /* Somebody messed up.. */
  864.  
  865.       default:
  866.     fprintf(stderr,
  867.         "ProcessOpt: invalid processing mode for option %s\n",
  868.         tab->opt);
  869.     return 1;
  870.     }
  871.     return 0;
  872. }
  873.  
  874. /*----------------------------------------------------------------------*\
  875.  * GetOptarg()
  876.  *
  877.  * Retrieves an option argument.
  878.  * If an error occurs here it is a true syntax error.
  879. \*----------------------------------------------------------------------*/
  880.  
  881. static int
  882. GetOptarg(char **poptarg, int *p_myargc, char ***p_argv, int *p_argc)
  883. {
  884.     int result = 0;
  885.  
  886.     --(*p_myargc);
  887.  
  888.     if ((*p_myargc) <= 0)        /* oops, no more arguments */
  889.     result = 1;
  890.  
  891.     if ( ! result) {
  892.     (*p_argv)++;
  893.     if ((*p_argv)[0][0] == '-' && isalpha((*p_argv)[0][1])) {
  894.  
  895.         (*p_argv)--;        /* oops, next arg is a flag */
  896.         result = 1;
  897.     }
  898.     }
  899.  
  900.     if ( ! result) {            /* yeah, the user got it right */
  901.     (*p_argc)--;
  902.     *poptarg = (*p_argv)[0];
  903.     }
  904.     else {
  905.     if ( ! mode_quiet) {
  906.         fprintf(stderr, "Argument missing for %s option.\n",
  907.             (*p_argv)[0]); 
  908.         (*UsageH) ("");
  909.     }
  910.     }
  911.     return result;
  912. }
  913.  
  914. /*----------------------------------------------------------------------*\
  915.  * Usage()
  916.  *
  917.  * Print usage & syntax message.
  918. \*----------------------------------------------------------------------*/
  919.  
  920. static void
  921. Usage(char *badOption)
  922. {
  923.     if (*badOption != '\0')
  924.     fprintf(stderr, "\n%s:  bad command line option \"%s\"\r\n",
  925.         program_name, badOption);
  926.  
  927.     fprintf(stderr, "\nUsage:\n        %s [plplot options]\n",
  928.         program_name);
  929.  
  930.     Syntax();
  931.  
  932.     fprintf(stderr, "\r\n\nType %s -h for a full description.\r\n\n",
  933.         program_name);
  934. }
  935.  
  936. /*----------------------------------------------------------------------*\
  937.  * Syntax()
  938.  *
  939.  * Print syntax message appropriate for plplot.
  940. \*----------------------------------------------------------------------*/
  941.  
  942. static void
  943. Syntax(void)
  944. {
  945.     PLOptionTable *tab;
  946.     int col, len;
  947.  
  948.     fprintf(stderr, "\nplplot options:");
  949.  
  950.     col = 80;
  951.     for (tab = ploption_table; tab->opt; tab++) {
  952.     if ( ! (tab->mode & PL_OPT_ENABLED))
  953.         continue;
  954.  
  955.     if ( ! mode_showall && (tab->mode & PL_OPT_INVISIBLE))
  956.         continue;
  957.  
  958.     if (tab->syntax == NULL)
  959.         continue;
  960.  
  961.     len = 3 + strlen(tab->syntax);        /* space [ string ] */
  962.     if (col + len > 79) {
  963.         fprintf(stderr, "\r\n   ");        /* 3 spaces */
  964.         col = 3;
  965.     }
  966.     fprintf(stderr, " [%s]", tab->syntax);
  967.     col += len;
  968.     }
  969.     fprintf(stderr, "\r\n");
  970. }
  971.  
  972. /*----------------------------------------------------------------------*\
  973.  * Help()
  974.  *
  975.  * Print long help message appropriate for plplot.
  976. \*----------------------------------------------------------------------*/
  977.  
  978. static void
  979. Help(void)
  980. {
  981.     PLOptionTable *tab;
  982.  
  983.     fprintf(stderr, "\nplplot options:\n");
  984.     for (tab = ploption_table; tab->opt; tab++) {
  985.     if ( ! (tab->mode & PL_OPT_ENABLED))
  986.         continue;
  987.  
  988.     if ( ! mode_showall && (tab->mode & PL_OPT_INVISIBLE))
  989.         continue;
  990.  
  991.     if (tab->desc == NULL)
  992.         continue;
  993.  
  994.     if (tab->mode & PL_OPT_INVISIBLE) 
  995.         fprintf(stderr, " *  %-20s %s\n", tab->syntax, tab->desc);
  996.     else 
  997.         fprintf(stderr, "    %-20s %s\n", tab->syntax, tab->desc);
  998.     }
  999. }
  1000.  
  1001. /*----------------------------------------------------------------------*\
  1002.  * Option handlers
  1003. \*----------------------------------------------------------------------*/
  1004.  
  1005. /*----------------------------------------------------------------------*\
  1006.  * opt_h()
  1007.  *
  1008.  * Performs appropriate action for option "h":
  1009.  * Issues help message
  1010. \*----------------------------------------------------------------------*/
  1011.  
  1012. static int
  1013. opt_h(char *opt, char *optarg, void *client_data)
  1014. {
  1015.     if ( ! mode_quiet) {
  1016.     fprintf(stderr, "\nUsage:\n        %s [plplot options]\n",
  1017.         program_name);
  1018.  
  1019.     Help();
  1020.     plNotes();
  1021.     }
  1022.     return 1;
  1023. }
  1024.  
  1025. /*----------------------------------------------------------------------*\
  1026.  * opt_v()
  1027.  *
  1028.  * Performs appropriate action for option "v":
  1029.  * Issues version message
  1030. \*----------------------------------------------------------------------*/
  1031.  
  1032. static int
  1033. opt_v(char *opt, char *optarg, void *client_data)
  1034. {
  1035.     if ( ! mode_quiet) {
  1036.     fprintf(stderr, "\nplplot library version: %s\n", PLPLOT_VERSION);
  1037.     }
  1038.     return 1;
  1039. }
  1040.  
  1041. /*----------------------------------------------------------------------*\
  1042.  * opt_hack()
  1043.  *
  1044.  * Performs appropriate action for option "hack":
  1045.  * Enables driver-specific hack(s)
  1046. \*----------------------------------------------------------------------*/
  1047.  
  1048. static int
  1049. opt_hack(char *opt, char *optarg, void *client_data)
  1050. {
  1051.     plsc->hack = 1;
  1052.     return 0;
  1053. }
  1054.  
  1055. /*----------------------------------------------------------------------*\
  1056.  * opt_dev()
  1057.  *
  1058.  * Performs appropriate action for option "dev":
  1059.  * Sets output device keyword
  1060. \*----------------------------------------------------------------------*/
  1061.  
  1062. static int
  1063. opt_dev(char *opt, char *optarg, void *client_data)
  1064. {
  1065.     plsdev(optarg);
  1066.     return 0;
  1067. }
  1068.  
  1069. /*----------------------------------------------------------------------*\
  1070.  * opt_o()
  1071.  *
  1072.  * Performs appropriate action for option "o":
  1073.  * Sets output file name
  1074. \*----------------------------------------------------------------------*/
  1075.  
  1076. static int
  1077. opt_o(char *opt, char *optarg, void *client_data)
  1078. {
  1079.     plsfnam(optarg);
  1080.     return 0;
  1081. }
  1082.  
  1083. /*----------------------------------------------------------------------*\
  1084.  * opt_mar()
  1085.  *
  1086.  * Performs appropriate action for option "mar":
  1087.  * Sets relative margin width
  1088. \*----------------------------------------------------------------------*/
  1089.  
  1090. static int
  1091. opt_mar(char *opt, char *optarg, void *client_data)
  1092. {
  1093.     plsdidev(atof(optarg), PL_NOTSET, PL_NOTSET, PL_NOTSET);
  1094.     return 0;
  1095. }
  1096.  
  1097. /*----------------------------------------------------------------------*\
  1098.  * opt_a()
  1099.  *
  1100.  * Performs appropriate action for option "a":
  1101.  * Sets plot aspect ratio on page
  1102. \*----------------------------------------------------------------------*/
  1103.  
  1104. static int
  1105. opt_a(char *opt, char *optarg, void *client_data)
  1106. {
  1107.     plsdidev(PL_NOTSET, atof(optarg), PL_NOTSET, PL_NOTSET);
  1108.     return 0;
  1109. }
  1110.  
  1111. /*----------------------------------------------------------------------*\
  1112.  * opt_jx()
  1113.  *
  1114.  * Performs appropriate action for option "jx":
  1115.  * Sets relative justification in x
  1116. \*----------------------------------------------------------------------*/
  1117.  
  1118. static int
  1119. opt_jx(char *opt, char *optarg, void *client_data)
  1120. {
  1121.     plsdidev(PL_NOTSET, PL_NOTSET, atof(optarg), PL_NOTSET);
  1122.     return 0;
  1123. }
  1124.  
  1125. /*----------------------------------------------------------------------*\
  1126.  * opt_jy()
  1127.  *
  1128.  * Performs appropriate action for option "jy":
  1129.  * Sets relative justification in y
  1130. \*----------------------------------------------------------------------*/
  1131.  
  1132. static int
  1133. opt_jy(char *opt, char *optarg, void *client_data)
  1134. {
  1135.     plsdidev(PL_NOTSET, PL_NOTSET, PL_NOTSET, atof(optarg));
  1136.     return 0;
  1137. }
  1138.  
  1139. /*----------------------------------------------------------------------*\
  1140.  * opt_ori()
  1141.  *
  1142.  * Performs appropriate action for option "ori":
  1143.  * Sets orientation
  1144. \*----------------------------------------------------------------------*/
  1145.  
  1146. static int
  1147. opt_ori(char *opt, char *optarg, void *client_data)
  1148. {
  1149.     plsdiori(atof(optarg));
  1150.     return 0;
  1151. }
  1152.  
  1153. /*----------------------------------------------------------------------*\
  1154.  * opt_width()
  1155.  *
  1156.  * Performs appropriate action for option "width":
  1157.  * Sets pen width
  1158. \*----------------------------------------------------------------------*/
  1159.  
  1160. static int
  1161. opt_width(char *opt, char *optarg, void *client_data)
  1162. {
  1163.     int width;
  1164.  
  1165.     width = atoi(optarg);
  1166.     if (width == 0) {
  1167.     fprintf(stderr, "?invalid width\n");
  1168.     return 1;
  1169.     }
  1170.     else {
  1171.     plwid(width);
  1172.     plsc->widthlock = 1;
  1173.     }
  1174.     return 0;
  1175. }
  1176.  
  1177. /*----------------------------------------------------------------------*\
  1178.  * opt_bg()
  1179.  *
  1180.  * Performs appropriate action for option "bg":
  1181.  * Sets background color
  1182. \*----------------------------------------------------------------------*/
  1183.  
  1184. static int
  1185. opt_bg(char *opt, char *optarg, void *client_data)
  1186. {
  1187.     char *rgb;
  1188.     long bgcolor, r, g, b;
  1189.  
  1190. /* Always in hex!  Strip off leading "#" (TK-ism) if present. */
  1191.  
  1192.     if (*optarg == '#')
  1193.     rgb = optarg + 1;
  1194.     else
  1195.     rgb = optarg;
  1196.  
  1197. /* Must be either a 3 or 6 digit hex number */
  1198. /* If 3 digits, each is "doubled" (i.e. ABC becomes AABBCC). */
  1199.  
  1200.     bgcolor = strtol(rgb, NULL, 16);
  1201.  
  1202.     switch (strlen(rgb)) {
  1203.     case 3:
  1204.     r = (bgcolor & 0xF00) >> 8;
  1205.     g = (bgcolor & 0x0F0) >> 4;
  1206.     b = (bgcolor & 0x00F);
  1207.  
  1208.     r = r | (r << 4);
  1209.     g = g | (g << 4);    /* doubling */
  1210.     b = b | (b << 4);
  1211.     break;
  1212.  
  1213.     case 6:
  1214.     r = (bgcolor & 0xFF0000) >> 16;
  1215.     g = (bgcolor & 0x00FF00) >> 8;
  1216.     b = (bgcolor & 0x0000FF);
  1217.     break;
  1218.  
  1219.     default:
  1220.     fprintf(stderr, "Unrecognized background color value %s\n", rgb);
  1221.     return 1;
  1222.     }
  1223.  
  1224.     plscolbg(r, g, b);
  1225.  
  1226.     return 0;
  1227. }
  1228.  
  1229. /*----------------------------------------------------------------------*\
  1230.  * opt_wplt()
  1231.  *
  1232.  * Performs appropriate action for option "wplt":
  1233.  * Sets (zoom) window into plot (e.g. "0,0,0.5,0.5")
  1234. \*----------------------------------------------------------------------*/
  1235.  
  1236. static int
  1237. opt_wplt(char *opt, char *optarg, void *client_data)
  1238. {
  1239.     char *field;
  1240.     float xl, yl, xr, yr;
  1241.  
  1242.     if ((field = strtok(optarg, ",")) == NULL)
  1243.     return 1;
  1244.  
  1245.     xl = atof(field);
  1246.  
  1247.     if ((field = strtok(NULL, ",")) == NULL)
  1248.     return 1;
  1249.  
  1250.     yl = atof(field);
  1251.  
  1252.     if ((field = strtok(NULL, ",")) == NULL)
  1253.     return 1;
  1254.  
  1255.     xr = atof(field);
  1256.  
  1257.     if ((field = strtok(NULL, ",")) == NULL)
  1258.     return 1;
  1259.  
  1260.     yr = atof(field);
  1261.  
  1262.     plsdiplt(xl, yl, xr, yr);
  1263.     return 0;
  1264. }
  1265.  
  1266. /*----------------------------------------------------------------------*\
  1267.  * opt_fam()
  1268.  *
  1269.  * Performs appropriate action for option "fam":
  1270.  * Enables family output files
  1271. \*----------------------------------------------------------------------*/
  1272.  
  1273. static int
  1274. opt_fam(char *opt, char *optarg, void *client_data)
  1275. {
  1276.     plsfam(1, -1, -1);
  1277.     return 0;
  1278. }
  1279.  
  1280. /*----------------------------------------------------------------------*\
  1281.  * opt_fsiz()
  1282.  *
  1283.  * Performs appropriate action for option "fsiz":
  1284.  * Sets size of a family member file (may be somewhat larger since eof must
  1285.  * occur at a page break).
  1286. \*----------------------------------------------------------------------*/
  1287.  
  1288. static int
  1289. opt_fsiz(char *opt, char *optarg, void *client_data)
  1290. {
  1291.     PLINT bytemax;
  1292.  
  1293.     bytemax = 1.0e6 * atof(optarg);
  1294.     if (bytemax == 0) {
  1295.     fprintf(stderr, "?invalid bytemax\n");
  1296.     return 1;
  1297.     }
  1298.     plsfam(-1, -1, bytemax);
  1299.  
  1300.     return 0;
  1301. }
  1302.  
  1303. /*----------------------------------------------------------------------*\
  1304.  * opt_fbeg()
  1305.  *
  1306.  * Performs appropriate action for option "fbeg":
  1307.  * Starts with the specified family member number.
  1308. \*----------------------------------------------------------------------*/
  1309.  
  1310. static int
  1311. opt_fbeg(char *opt, char *optarg, void *client_data)
  1312. {
  1313.     plsc->member = atoi(optarg);
  1314.  
  1315.     return 0;
  1316. }
  1317.  
  1318. /*----------------------------------------------------------------------*\
  1319.  * opt_finc()
  1320.  *
  1321.  * Performs appropriate action for option "finc":
  1322.  * Specify increment between family members.
  1323. \*----------------------------------------------------------------------*/
  1324.  
  1325. static int
  1326. opt_finc(char *opt, char *optarg, void *client_data)
  1327. {
  1328.     plsc->finc = atoi(optarg);
  1329.  
  1330.     return 0;
  1331. }
  1332.  
  1333. /*----------------------------------------------------------------------*\
  1334.  * opt_fflen()
  1335.  *
  1336.  * Performs appropriate action for option "fflen":
  1337.  * Specify minimum field length for family member number.
  1338. \*----------------------------------------------------------------------*/
  1339.  
  1340. static int
  1341. opt_fflen(char *opt, char *optarg, void *client_data)
  1342. {
  1343.     plsc->fflen = atoi(optarg);
  1344.  
  1345.     return 0;
  1346. }
  1347.  
  1348. /*----------------------------------------------------------------------*\
  1349.  * opt_np()
  1350.  *
  1351.  * Performs appropriate action for option "np":
  1352.  * Disables pause between pages
  1353. \*----------------------------------------------------------------------*/
  1354.  
  1355. static int
  1356. opt_np(char *opt, char *optarg, void *client_data)
  1357. {
  1358.     plspause(0);
  1359.     return 0;
  1360. }
  1361.  
  1362. /*----------------------------------------------------------------------*\
  1363.  * opt_nopixmap()
  1364.  *
  1365.  * Performs appropriate action for option "nopixmap":
  1366.  * Disables use of pixmaps in X drivers
  1367. \*----------------------------------------------------------------------*/
  1368.  
  1369. static int
  1370. opt_nopixmap(char *opt, char *optarg, void *client_data)
  1371. {
  1372.     plsc->nopixmap = 1;
  1373.     return 0;
  1374. }
  1375.  
  1376. /*----------------------------------------------------------------------*\
  1377.  * opt_db()
  1378.  *
  1379.  * Performs appropriate action for option "db":
  1380.  * Double buffer X output (update only done on eop or Expose)
  1381. \*----------------------------------------------------------------------*/
  1382.  
  1383. static int
  1384. opt_db(char *opt, char *optarg, void *client_data)
  1385. {
  1386.     plsc->db = 1;
  1387.     return 0;
  1388. }
  1389.  
  1390. /*----------------------------------------------------------------------*\
  1391.  * opt_bufmax()
  1392.  *
  1393.  * Performs appropriate action for option "bufmax":
  1394.  * Sets size of data buffer for tk driver
  1395. \*----------------------------------------------------------------------*/
  1396.  
  1397. static int
  1398. opt_bufmax(char *opt, char *optarg, void *client_data)
  1399. {
  1400.     plsc->bufmax = atoi(optarg);
  1401.     return 0;
  1402. }
  1403.  
  1404. /*----------------------------------------------------------------------*\
  1405.  * opt_server_name()
  1406.  *
  1407.  * Performs appropriate action for option "server_name":
  1408.  * Sets main window name of server (Tcl/TK/DP driver only)
  1409. \*----------------------------------------------------------------------*/
  1410.  
  1411. static int
  1412. opt_server_name(char *opt, char *optarg, void *client_data)
  1413. {
  1414.     plsc->server_name = optarg;
  1415.     return 0;
  1416. }
  1417.  
  1418. /*----------------------------------------------------------------------*\
  1419.  * opt_server_host()
  1420.  *
  1421.  * Performs appropriate action for option "server_host":
  1422.  * Sets host to run server on (Tcl/TK/DP driver only)
  1423. \*----------------------------------------------------------------------*/
  1424.  
  1425. static int
  1426. opt_server_host(char *opt, char *optarg, void *client_data)
  1427. {
  1428.     plsc->server_host = optarg;
  1429.     return 0;
  1430. }
  1431.  
  1432. /*----------------------------------------------------------------------*\
  1433.  * opt_server_port()
  1434.  *
  1435.  * Performs appropriate action for option "server_port":
  1436.  * Sets port to talk to server on (Tcl/TK/DP driver only)
  1437. \*----------------------------------------------------------------------*/
  1438.  
  1439. static int
  1440. opt_server_port(char *opt, char *optarg, void *client_data)
  1441. {
  1442.     plsc->server_port = optarg;
  1443.     return 0;
  1444. }
  1445.  
  1446. /*----------------------------------------------------------------------*\
  1447.  * opt_user()
  1448.  *
  1449.  * Performs appropriate action for option "user":
  1450.  * Sets user name on remote node (for remsh), dp driver only
  1451. \*----------------------------------------------------------------------*/
  1452.  
  1453. static int
  1454. opt_user(char *opt, char *optarg, void *client_data)
  1455. {
  1456.     plsc->user = optarg;
  1457.     return 0;
  1458. }
  1459.  
  1460. /*----------------------------------------------------------------------*\
  1461.  * opt_plserver()
  1462.  *
  1463.  * Performs appropriate action for option "plserver":
  1464.  * Sets name to use when invoking server (Tcl/TK/DP driver only)
  1465. \*----------------------------------------------------------------------*/
  1466.  
  1467. static int
  1468. opt_plserver(char *opt, char *optarg, void *client_data)
  1469. {
  1470.     plsc->plserver = optarg;
  1471.     return 0;
  1472. }
  1473.  
  1474. /*----------------------------------------------------------------------*\
  1475.  * opt_plwindow()
  1476.  *
  1477.  * Performs appropriate action for option "plwindow":
  1478.  * Sets plplot window name
  1479. \*----------------------------------------------------------------------*/
  1480.  
  1481. static int
  1482. opt_plwindow(char *opt, char *optarg, void *client_data)
  1483. {
  1484.     plsc->plwindow = optarg;
  1485.     return 0;
  1486. }
  1487.  
  1488. /*----------------------------------------------------------------------*\
  1489.  * opt_tcl_cmd()
  1490.  *
  1491.  * Performs appropriate action for option "tcl_cmd":
  1492.  * Sets TCL command(s) to eval on startup
  1493. \*----------------------------------------------------------------------*/
  1494.  
  1495. static int
  1496. opt_tcl_cmd(char *opt, char *optarg, void *client_data)
  1497. {
  1498.     plsc->tcl_cmd = optarg;
  1499.     return 0;
  1500. }
  1501.  
  1502. /*----------------------------------------------------------------------*\
  1503.  * opt_auto_path()
  1504.  *
  1505.  * Performs appropriate action for option "auto_path":
  1506.  * Sets additional directories to autoload
  1507. \*----------------------------------------------------------------------*/
  1508.  
  1509. static int
  1510. opt_auto_path(char *opt, char *optarg, void *client_data)
  1511. {
  1512.     plsc->auto_path = optarg;
  1513.     return 0;
  1514. }
  1515.  
  1516. /*----------------------------------------------------------------------*\
  1517.  * opt_px()
  1518.  *
  1519.  * Performs appropriate action for option "px":
  1520.  * Set packing in x
  1521. \*----------------------------------------------------------------------*/
  1522.  
  1523. static int
  1524. opt_px(char *opt, char *optarg, void *client_data)
  1525. {
  1526.     plssub(atoi(optarg), -1);
  1527.     return 0;
  1528. }
  1529.  
  1530. /*----------------------------------------------------------------------*\
  1531.  * opt_py()
  1532.  *
  1533.  * Performs appropriate action for option "py":
  1534.  * Set packing in y
  1535. \*----------------------------------------------------------------------*/
  1536.  
  1537. static int
  1538. opt_py(char *opt, char *optarg, void *client_data)
  1539. {
  1540.     plssub(-1, atoi(optarg));
  1541.     return 0;
  1542. }
  1543.  
  1544. /*----------------------------------------------------------------------*\
  1545.  * opt_geo()
  1546.  *
  1547.  * Performs appropriate action for option "geo":
  1548.  * Set geometry for output window (e.g. "400x400+100+0")
  1549. \*----------------------------------------------------------------------*/
  1550.  
  1551. static int
  1552. opt_geo(char *opt, char *optarg, void *client_data)
  1553. {
  1554.     char *field;
  1555.     PLFLT xdpi = 0., ydpi = 0.;
  1556.     PLINT xwid, ywid, xoff = 0, yoff = 0;
  1557.  
  1558. /* The TK driver uses the geometry string directly */
  1559.  
  1560.     plsc->geometry = (char *) malloc((size_t)(1+strlen(optarg))*sizeof(char));
  1561.     strcpy(plsc->geometry, optarg);
  1562.  
  1563.     if ((field = strtok(optarg, "x")) == NULL)
  1564.     return 1;
  1565.  
  1566.     xwid = atoi(field);
  1567.     if (xwid == 0) {
  1568.     fprintf(stderr, "?invalid xwid\n");
  1569.     return 1;
  1570.     }
  1571.  
  1572.     if ((field = strtok(NULL, "+")) == NULL)
  1573.     return 1;
  1574.  
  1575.     ywid = atoi(field);
  1576.     if (ywid == 0) {
  1577.     fprintf(stderr, "?invalid ywid\n");
  1578.     return 1;
  1579.     }
  1580.  
  1581.     if ((field = strtok(NULL, "+")) != NULL) {
  1582.     xoff = atoi(field);
  1583.  
  1584.     if ((field = strtok(NULL, "+")) != NULL)
  1585.         yoff = atoi(field);
  1586.     }
  1587.  
  1588.     plspage(xdpi, ydpi, xwid, ywid, xoff, yoff);
  1589.     return 0;
  1590. }
  1591.